package com.zzh.mvvm.base;

import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.Window;

import com.zzh.mvvm.base.vm.BaseViewModel;
import com.zzh.mvvm.bus.Messenger;
import com.zzh.mvvm.container.ContainerActivity;
import com.zzh.mvvm.factory.HRabbitFactory;
import com.zzh.mvvm.kb.KeyboardAction;
import com.zzh.mvvm.rabbit.IBaseView;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

/**
 * @date: 2021/9/9 14:23
 * @email: zzh_hz@126.com
 * @QQ: 1299234582
 * @author: zzh
 * @description: activity 基类，封装业务层，BaseViewModel，findViewById ViewBinding，
 */
public abstract class BaseRabbitActivity<VM extends BaseViewModel, VB extends ViewDataBinding> extends AppCompatActivity implements IBaseView, KeyboardAction {
    protected VB bind;
    protected VM viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //私有的初始化Databinding和ViewModel方法
        bind = initViewBinding(savedInstanceState);
        checkSafeNullBinding(getLayoutInflater());
        setContentView(bind.getRoot());
        viewModel = initViewModel(savedInstanceState);
        checkSafeNullViewModel();
        bind.setVariable(initVariableId(), viewModel);
        bind.setLifecycleOwner(this);
        registerUIChangeLiveDataCallBack();
        initViewAndData(savedInstanceState);
        setListener();
        //注册RxBus
        viewModel.registerRxBus();
    }


    /**
     * 初始化ViewBinding数据
     *
     * @param savedInstanceState
     * @return
     */
    protected VB initViewBinding(Bundle savedInstanceState) {
        return null;
    }

    /**
     * 校验ViewModel不为空，如果不初始化，则默认赋值。
     */
    protected void checkSafeNullBinding(LayoutInflater layoutInflater) {

        if (bind == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[getBindingActualTypeIndex()];
                try {
                    Method bindCreateMethod = modelClass.getMethod("inflate", LayoutInflater.class);
                    bindCreateMethod.setAccessible(true);
                    bind = (VB) bindCreateMethod.invoke(null, layoutInflater);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    protected int getBindingActualTypeIndex() {
        return 1;
    }

    /**
     * 初始化ViewModel
     *
     * @param savedInstanceState 状态保存
     * @return
     */
    protected VM initViewModel(Bundle savedInstanceState) {
        return null;
    }

    /**
     * 校验ViewModel不为空，如果不初始化，则默认赋值。
     */
    protected void checkSafeNullViewModel() {
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = BaseViewModel.class;
            }
            viewModel = (VM) createViewModel(this, modelClass);
        }
        getLifecycle().addObserver(viewModel);
    }

    /**
     * 数据，view 逻辑
     *
     * @param savedInstanceState 保存数据
     */
    protected abstract void initViewAndData(Bundle savedInstanceState);

    protected abstract int initVariableId();

    /**
     * 设置监听事件
     */
    public void setListener() {
        getContentView().setOnClickListener(v -> hideKeyboard(getCurrentFocus()));
    }

    public ViewGroup getContentView() {
        return findViewById(Window.ID_ANDROID_CONTENT);
    }

    @Override
    protected void onDestroy() {
        if (viewModel != null) {
            getLifecycle().removeObserver(viewModel);
        }
        hideKeyboard(getCurrentFocus());
        super.onDestroy();
        //解除Messenger注册
        Messenger.getDefault().unregister(viewModel);
        if (viewModel != null) {
            viewModel.removeRxBus();
        }
    }


    /**
     * 注册ViewModel与View的契约UI回调事件
     **/
    protected void registerUIChangeLiveDataCallBack() {
        //加载对话框显示
        viewModel.getUC().getShowDialogEvent().observe(this, (Observer<String>) title -> showDialog(title));
        //加载对话框消失
        viewModel.getUC().getDismissDialogEvent().observe(this, (Observer<Void>) v -> dismissDialog());
        //跳入新页面
        viewModel.getUC().getStartActivityEvent().observe(this, (Observer<Map<String, Object>>) params -> {
            Class<?> clz = (Class<?>) params.get(BaseViewModel.ParameterField.CLASS);
            Bundle bundle = (Bundle) params.get(BaseViewModel.ParameterField.BUNDLE);
            startActivity(clz, bundle);
        });
        //跳入ContainerActivity
        viewModel.getUC().getStartContainerActivityEvent().observe(this, (Observer<Map<String, Object>>) params -> {
            String canonicalName = (String) params.get(BaseViewModel.ParameterField.CANONICAL_NAME);
            Bundle bundle = (Bundle) params.get(BaseViewModel.ParameterField.BUNDLE);
            startContainerActivity(canonicalName, bundle);
        });
        //关闭界面
        viewModel.getUC().getFinishEvent().observe(this, (Observer<Void>) v -> finish());
        //关闭上一层
        viewModel.getUC().getOnBackPressedEvent().observe(this, (Observer<Void>) v -> onBackPressed());
    }

    /**
     * 子类显示弹出框样式，并显示出来
     *
     * @param title 标题
     */
    public void showDialog(String title) {

    }

    /**
     * 隐藏弹出框
     */
    public void dismissDialog() {

    }

    /**
     * 跳转页面
     *
     * @param clz 所跳转的目的Activity类
     */
    public void startActivity(Class<?> clz) {
        startActivity(new Intent(this, clz));
    }

    /**
     * 跳转页面
     *
     * @param clz    所跳转的目的Activity类
     * @param bundle 跳转所携带的信息
     */
    public void startActivity(Class<?> clz, Bundle bundle) {
        Intent intent = new Intent(this, clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    /**
     * 跳转容器页面
     *
     * @param canonicalName 规范名 : Fragment.class.getCanonicalName()
     */
    public void startContainerActivity(String canonicalName) {
        startContainerActivity(canonicalName, null);
    }

    /**
     * 跳转容器页面
     *
     * @param canonicalName 规范名 : Fragment.class.getCanonicalName()
     * @param bundle        跳转所携带的信息
     */
    public void startContainerActivity(String canonicalName, Bundle bundle) {
        Intent intent = new Intent(this, ContainerActivity.class);
        intent.putExtra(ContainerActivity.FRAGMENT, canonicalName);
        if (bundle != null) {
            intent.putExtra(ContainerActivity.BUNDLE, bundle);
        }
        startActivity(intent);
    }


    /**
     * 创建ViewModel
     *
     * @param cls ViewModel的class
     * @param <T> ViewModel子类
     * @return AndroidViewModel 实例
     */
    public <T extends AndroidViewModel> T createViewModel(FragmentActivity activity, Class<T> cls) {
        ViewModelProvider.AndroidViewModelFactory instance = HRabbitFactory.getSubInstance(getApplication());
        return new ViewModelProvider(activity, instance).get(cls);
    }
}
